package com.ljy.my_study.json转对象.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/** 
* @author James
* @date 2018年8月25日 
*/
public class ParamNodeCreater {
	
	public static List<ParamNode> getParamNodeList(String className,Map<String,Object> map) {
		Map<String,ParamNode> paramMap=new HashMap<>();
		ParamNode rootParamNode=createRootParamNode(className,map,paramMap);
		paramMap.put("TestObj", rootParamNode);
		return new ArrayList<>(paramMap.values());
	}
	
	private static ParamNode createRootParamNode(String className,Map<String,Object> map,Map<String,ParamNode> paramMap) {
		ParamNode p=new ParamNode();
		p.setClassName(className);
		p.setIsCustomObject(1);
		p.setIsRoot(1);
		List<ParamNode> paramNodeList=createParamsMap(map,paramMap);
		p.setObj(paramNodeList);
		return p;
	}
	
	private static List<ParamNode> createParamsMap(Map<String,Object> map,Map<String,ParamNode> paramMap) {
		if(map==null||map.isEmpty()) {
			return null;
		}
		List<ParamNode> paramNodeList=new ArrayList<>();
		for(Entry<String,Object> e:map.entrySet()) {
			Object value=e.getValue();
			ParamNode p=createNode(e.getKey(),value,paramMap);
			
			paramNodeList.add(p);
		}
		return paramNodeList;
	}
	
	private static ParamNode createNode(String key,Object value,Map<String,ParamNode> paramMap) {
		ParamNode p=new ParamNode();
		p.setFieldName(key.trim());
		if(value==null) {
			p.setObj(String.class);
			p.setClassName("String");
		}else if(value.getClass()==LinkedHashMap.class) {
			p.setIsCustomObject(1);
			p.setObj(createParamsMap(((LinkedHashMap<String,Object>)value),paramMap));
			addParamToMap(p,paramMap);
		}else if(value.getClass()==Integer.class) {
			p.setObj(Integer.class);
			p.setClassName("Integer");
		}else if(value.getClass()==String.class) {
			if(isDate((String)value)) {
				p.setObj(Date.class);
				p.setClassName("Date");
			}else {
				p.setObj(String.class);
				p.setClassName("String");
			}
		}else if(value.getClass()==Double.class) {
			p.setObj(Double.class);
			p.setClassName("Double");
		}else if(value.getClass()==ArrayList.class) {
			p.setIsList(1);
			p.setClassName("List");
			if(((ArrayList)value).isEmpty()) {
				p.setObj(String.class);
				p.setListSubClassName("String");
			}else {
				Object obj=((ArrayList)value).get(0);
				ParamNode subParamNode=createNode(key,obj,paramMap);
				p.setObj(subParamNode);
				String subClassName=subParamNode.getClassName();
				p.setListSubClassName(subClassName);
			}
		}else if(value.getClass()==Boolean.class){
			p.setObj(Boolean.class);
			p.setClassName("Boolean");
		}

		addDescAndChangeClassName(p,value);
		return p;
	}

	private static void addDescAndChangeClassName(ParamNode p,Object value){
		if(!p.getClassName().equals("String")){
			return;
		}
		String valueStr=value.toString();
		String[] arr=valueStr.split("->");
		boolean changeError=false;
		try{
			Integer.valueOf(arr[0]);
			p.setClassName("Integer");
		}catch (Exception e){
			changeError=true;
		}
		if(changeError){
			try{
				Double.valueOf(arr[0]);
				p.setClassName("Double");
				changeError=false;
			}catch (Exception e){
				changeError=true;
			}
		}
		if(arr.length==2){
			p.setDesc(arr[1]);
		}
	}
	
	private static void addParamToMap(ParamNode p,Map<String,ParamNode> paramMap) {
		if(p.getIsCustomObject()!=null&&p.getIsCustomObject()==1) {
			String fieldName=p.getFieldName();
			if(fieldName==null||fieldName.isEmpty()) {
				fieldName="null";
			}
			String className=fieldName.substring(0, 1).toUpperCase()+fieldName.substring(1);
			String className2=null;
			int count=0;
			do {
				if(count==0) {
					className2=className;
				}else {
					className2=className+count;
				}
				count++;
			}while(paramMap.containsKey(className2));
			p.setClassName(className2);
			paramMap.put(className2, p);
		}
	}
	
	private static boolean isDate(String dateStr) {
		if(dateStr==null||dateStr.isEmpty()) {
			return false;
		}
		if(dateStr.matches("(([0-9]{4})-([0-9]{2})-([0-9]{2}))((('T')|(T))([0-9]{2}):([0-9]{2}):([0-9]{2})(.[0-9]{3}){0,1}(('Z')|(Z))){0,1}")) {
			return true;
		}else {
			return false;
		}
	}
	
	public static void main(String[] args) {
		System.out.println(isDate("2018-08-24'T'12:15:21.120'Z'"));
		System.out.println(isDate("2018-08-20"));
		System.out.println(isDate("2018-08-20T00:00:00.000Z"));
	}
}
